采用 Org-publish 写博客
本站的内容使用 Emacs 编辑 org-mode 文件,使用 org-publish 导出为 html 文件,布署于 Github 之上。
我的博客源文档放置于私有 Github 仓库中,通过 Github actions 推送到开源的 jousimies.github.io 仓库中。
博客的架构如下:
├── build.el ├── init.el ├── org │ ├── about.org │ ├── index.org │ └── posts │ ├── 采用 Org-publish 写博客.org │ └── 我的博客的CSS配置文件.org └── static ├── js │ └── main.js └── style.css
Emacs 中的基本配置 init.el
内容如下:
(require 'ox-publish) (defvar my/blog-nav-html "<a href=\"/index.html\">首页</a> <a href=\"/about.html\">关于</a>" "博客页面导航栏 HTML 片段。") (setq org-publish-project-alist `( ("blog-org" :base-directory "./org/" :base-extension "org" :publishing-directory "./public/" :recursive t :html-head "<link rel=\"stylesheet\" href=\"/static/style.css\" />" :html-head-extra "<script src=\"/static/js/main.js\"></script>" :html-preamble nil :html-preamble-format (("en" ,my/blog-nav-html)) :html-postamble t :html-postamble-format (("en" "<hr><div class=\"info\"> <span class=\"created\">Created with %c on MacOS</span> <span class=\"updated\">Updated: %d</span> </div>")) :with-toc t :section-numbers nil :with-author nil :with-creator nil :with-date t :publishing-function org-html-publish-to-html ) ("blog-static" :base-directory "./static/" :base-extension "css\\|js\\|png\\|jpg\\|svg\\|ico" :publishing-directory "./public/static/" :recursive t :publishing-function org-publish-attachment) ("blog" :components ("blog-org" "blog-static")))) (defun my/org-blog-update-recent () "根据 org 文件更新时间生成 recent.org 文件,用于首页显示最近更新文章列表。" (interactive) (let* ((org-dir "./org") (files (directory-files (expand-file-name "posts" org-dir) t "\\.org$")) (recent-files (sort files (lambda (a b) (time-less-p (nth 5 (file-attributes b)) (nth 5 (file-attributes a)))))) (top-5 (seq-take recent-files 5))) (with-temp-file (expand-file-name "recent.org" org-dir) (insert "* 最近更新\n") (dolist (f top-5) (let* ((filename (file-name-nondirectory f)) (title (with-temp-buffer (insert-file-contents f) (goto-char (point-min)) (if (re-search-forward "^#\\+TITLE: \\(.*\\)" nil t) (match-string 1) filename)))) (insert (format "- [[file:posts\\%s][%s]]\n" filename title))))))) (defun my/publish-blog () "一键发布博客" (interactive) (org-publish "blog" t))
build.el
中的内容如下:
(require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize) (unless package-archive-contents (package-refresh-contents)) ;; 安装 org 包(如果你依赖 org-plus-contrib,请根据需要改) (unless (package-installed-p 'org) (package-install 'org)) (unless (package-installed-p 'htmlize) (package-install 'htmlize)) ;; 加载你的 publish 设置 (load-file "init.el") ;; 执行发布 (org-publish-all t) (message "Blog published successfully.")
默认导出的 html 文件非常的简单,需要结合 CSS 文件 和 JS 文件,以实现高阶的需求,比如界面的美化、回到上一页、回到首页的功能、侧边栏、动态目录等等。
关于 Github actions 的使用,问 Chatgpt 就好啦,需要注意使用 personal_token
。我的配置如下:
name: Deploy Blog on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup Emacs uses: purcell/setup-emacs@master with: version: 30.1 - name: Install Org and dependencies run: emacs --batch -l build.el - name: Publish blog run: emacs --batch -l init.el -f org-publish-all - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: personal_token: ${{ secrets.GH_PAT }} publish_dir: ./public external_repository: Jousimies/jousimies.github.io publish_branch: main